﻿#region Using Statments

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime;
using System.Runtime.InteropServices;
using System.Text;

#endregion

#region Disclaimer

/*
    Copyright (c) <2010>, Michael T. Joiner
    All rights reserved.

    Redistribution and use in source and binary forms, with or without modification, 
    are permitted provided that the following conditions are met:
   
    Redistributions of source code must retain the above copyright notice, this list 
    of conditions and the following disclaimer.
    
    Redistributions in binary form must reproduce the above copyright notice, this list 
    of conditions and the following disclaimer in the documentation and/or other materials 
    provided with the distribution.
    
    Neither the name of the Copyright holder nor the names of its contributors 
    may be used to endorse or promote products derived from this software without 
    specific prior written permission.
    
    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 
    ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 
    THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
    OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE..
 
 */

#endregion

#region File Description
/*
    /////////////////////////////////////////////////////////////////////////////////////////
    
                                  <Struct FILE> DESCRIPTION
                                -----------------------------
    [Enter File Description Info Here]
    
    /////////////////////////////////////////////////////////////////////////////////////////
*/
#endregion

namespace SlimGame.Framework.Graphics
{
    public struct Color
    {
        #region Fields

        #region Constant Fields

        private const float MaxValue = 1.0f;
        private const float MinValue = 0.0f;

        #endregion

        private float _Red;
        private float _Green;
        private float _Blue;
        private float _Alpha;

        #endregion

        #region Properties

        private float R
        {
            get { return _Red; }
            set { _Red = GetFixedValue(ref value); }
        }

        private float G
        {
            get { return _Green; }
            set { _Green = GetFixedValue(ref value); }
        }

        private float B
        {
            get { return _Blue; }
            set { _Blue = GetFixedValue(ref value); }
        }

        private float A
        {
            get { return _Alpha; }
            set { _Alpha = GetFixedValue(ref value); }
        }

        #region Static Properties

        // NOT ALL Members Assoicated with Color Values Yet!!

        public static Color AliceBlue 
        {
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color AntiqueWhite 
        {
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); }
        }

        public static Color Aqua 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Aquamarine 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Azure 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Beige 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Bisque 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Black 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color BlanchedAlmond 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Blue 
        { 
           get { return new Color(0.0f, 0.0f, 1.0f, 1.0f); } 
        }

        public static Color BlueViolet 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Brown 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color BurlyWood 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color CadetBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Chartreuse 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Chocolate 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Coral 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color CornflowerBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Cornsilk 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Crimson 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Cyan 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkCyan 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkGoldenrod 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkGray 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkGreen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkKhaki 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkMagenta 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkOliveGreen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkOrange 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkOrchid 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkRed 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkSalmon 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkSeaGreen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkSlateBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkSlateGray 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkTurquoise 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DarkViolet 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DeepPink 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DeepSkyBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DimGray 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color DodgerBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Firebrick 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color FloralWhite 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color ForestGreen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Fuchsia 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Gainsboro 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color GhostWhite 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Gold 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Goldenrod 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Gray 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Green 
        { 
           get { return new Color(0.0f, 1.0f, 0.0f, 1.0f); } 
        }

        public static Color GreenYellow 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Honeydew 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color HotPink 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color IndianRed 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Indigo 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Ivory 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Khaki 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Lavender 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LavenderBlush 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LawnGreen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LemonChiffon 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LightBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LightCoral 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LightCyan 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LightGoldenrodYellow 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LightGreen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LightGray 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LightPink 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LightSalmon 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LightSeaGreen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LightSkyBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LightSlateGray 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LightSteelBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LightYellow 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Lime 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color LimeGreen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Linen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Magenta 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Maroon 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color MediumAquamarine 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color MediumBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color MediumOrchid 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color MediumPurple 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color MediumSeaGreen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color MediumSlateBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color MediumSpringGreen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color MediumTurquoise 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color MediumVioletRed 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color MidnightBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color MintCream 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color MistyRose 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Moccasin 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color NavajoWhite 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Navy 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color OldLace 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Olive 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color OliveDrab 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Orange 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color OrangeRed 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Orchid 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color PaleGoldenrod 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color PaleGreen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color PaleTurquoise 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color PaleVioletRed 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color PapayaWhip 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color PeachPuff 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Peru 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Pink 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Plum 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color PowderBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Purple 
        { 
           get { return new Color(1.0f, 0.0f, 1.0f, 1.0f); } 
        }

        public static Color Red 
        { 
           get { return new Color(1.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color RosyBrown 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color RoyalBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color SaddleBrown 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Salmon 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color SandyBrown 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color SeaGreen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color SeaShell 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Sienna 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Silver 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color SkyBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color SlateBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color SlateGray 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Snow 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color SpringGreen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color SteelBlue 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Tan 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Teal 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Thistle 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Tomato 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color TransparentBlack
        {
           get { return new Color(0.0f, 0.0f, 0.0f, 0.0f); }
        }

        public static Color TransparentWhite
        {
           get { return new Color(1.0f, 1.0f, 1.0f, 0.0f); }
        }

        public static Color TransparentMagenta
        {
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); }
        }

        public static Color Turquoise 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Violet 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Wheat 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color White 
        { 
           get { return new Color(1.0f, 1.0f, 1.0f, 1.0f); } 
        }

        public static Color WhiteSmoke 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); } 
        }

        public static Color Yellow 
        { 
           get { return new Color(1.0f, 1.0f, 0.0f, 1.0f); } 
        }

        public static Color YellowGreen 
        { 
           get { return new Color(0.0f, 0.0f, 0.0f, 1.0f); }
        }

        #endregion

        #endregion

        public Color(float red, float green, float blue)
            : this(red, green, blue, 1.0f) { }

        public Color (float red, float green, float blue, float alpha)
        {
            this._Red = 0.0f;
            this._Green = 0.0f;
            this._Blue = 0.0f;
            this._Alpha = 0.0f;

            this._Red = GetFixedValue(ref red);
            this._Green = GetFixedValue(ref green);
            this._Blue = GetFixedValue(ref blue);
            this._Alpha = GetFixedValue(ref alpha);
        }

        public Color(Vector3 color) 
            : this(color.X, color.Y, color.Z, 1.0f) { }

        public Color(Vector4 color)
            : this(color.X, color.Y, color.Z, color.W) { }

        private float GetFixedValue(ref float val)
        {
            if (val <= MaxValue)
                if (val >= MinValue)
                    return val;
                else
                    return 0.0f;
            else
                return 1.0f;
        }

        public float GetBrightness()
        {
            float brightness = 0.0f;
            GetBrightness(ref brightness);
            return brightness;
        }

        public void GetBrightness(ref float brightness)
        {
            brightness = (_Red + _Green + _Blue) / 3.0f;
        }

        /*  Non Implemented Members


        public float GetHue()
        {
            throw new NotImplementedException();
        }
                
        public void GetHue(ref float hue)
        {
            throw new NotImplementedException();
        }

        public float GetSaturation()
        {
            throw new NotImplementedException();
        }

        public void GetSaturation(ref float saturation)
        {
            throw new NotImplementedException();
        }

        */

        public Vector3 ToVector3()
        {
            return new Vector3(_Red, _Green, _Blue);
        }

        public void ToVector3(ref Vector3 vector)
        {
            vector.X = _Red;
            vector.Y = _Green;
            vector.Z = _Blue;
        }

        public Vector4 ToVector4()
        {
            return new Vector4(_Red, _Green, _Blue, _Alpha);
        }

        public void ToVector4(ref Vector4 vector)
        {
            vector.X = _Red;
            vector.Y = _Green;
            vector.Z = _Blue;
            vector.W = _Alpha;
        }

        #region Operators 

        public static bool operator ==(Color color1, Color color2)
        {
            if (color1.R == color2.R && 
                color1.G == color2.G && 
                color1.B == color2.B && 
                color1.A == color2.A)
                return true;

            return false;
        }

        public static bool operator !=(Color color1, Color color2)
        {
            return !(color1 == color2);
        }

        public override bool Equals(object obj)
        {            
            return base.Equals(obj);
        }

        public override int GetHashCode()
        {
            return base.GetHashCode();
        }

        public override string ToString()
        {
            return base.ToString();
        }

        #endregion
    }
}
